import BaseChart from '@/comps/BaseChart';
import React from 'react';
import { debounce } from 'ronds-react-ui';
import Label from '../tags';
import { Guid } from '../utils';
import { rgbaChangeAlpha } from '../utils/colors';
import { LABEL_TYPES } from '../utils/constant';
import { IbrushData, ILabel, ITimeSeriesProps } from '../utils/types';

const RzTimeSeries = (props: ITimeSeriesProps) => {
  const { topic, title, secondKey, secondData, value, label, defalutData, className = 'rz-time-series', style, onNodeClick, onBrushChange } = props;

  const tsRef = React.useRef<any>(null);

  // 判断是否为首次渲染
  const firstRender = React.useRef<boolean>(true);

  const [isChartLoaded, setIsChartLoaded] = React.useState<boolean>(false);

  const [curLabel, setCurLabel] = React.useState<ILabel>({});
  const [curIndex, setCurIndex] = React.useState<number>(0);
  const curLabelRef = React.useRef<ILabel>(curLabel);
  const curIndexRef = React.useRef<number>(curIndex);

  const yPosition = React.useRef<{ min: number; max: number }>({ min: 0, max: 0 });

  const [curPosition, setCurPosition] = React.useState<{ start: number; end: number }>({ start: 0, end: 0 });

  const [brushData, setBrushData] = React.useState<IbrushData[]>([]);
  const brushDataRef = React.useRef<IbrushData[]>(brushData);

  // 初始化数据
  // React.useEffect(() => {
  //   if (!isChartLoaded) return;
  //   console.log('初始化数据==');
  //   // 首次渲染时候执行
  //   if (firstRender.current && defalutData) {
  //     console.log('defalutData');
  //     console.log(defalutData);
  //     // 将初始化数据处理成curLabelRef 数据用于回显
  //     const _curLabel = curLabel;
  //     const areas = [];
  //     for (let i = 0; i < defalutData.length; i++) {
  //       if (defalutData[i].type !== LABEL_TYPES.TIME_SERIES) {
  //         const idx = label.findIndex((v) => v.type === defalutData[i].type);

  //         _curLabel[`${idx}`] = {
  //           value:
  //             defalutData[i].type === LABEL_TYPES.MULTIPLE_CHOICES
  //               ? defalutData[i].value[defalutData[i].type]
  //               : defalutData[i].value[defalutData[i].type][0],
  //           color: '',
  //         };
  //       } else {
  //         const fill = rgbaChangeAlpha(defalutData[i].value.color, 0.4);
  //         const stroke = rgbaChangeAlpha(defalutData[i].value.color, 0.6);
  //         const _start = defalutData[i].value.start;
  //         const _end = defalutData[i].value.end;

  //         const config = {
  //           id: defalutData[i].id,
  //           draggable: 'x',
  //           shapes: [
  //             {
  //               type: 'path',
  //               strokeWidth: 1,
  //               stroke,
  //               fill,
  //               points: [
  //                 {
  //                   x: _start,
  //                   y: tsRef.current.hchartInstance.yAxis[0].min,
  //                   xAxis: 0,
  //                   yAxis: 0,
  //                 },
  //                 {
  //                   x: _end,
  //                   y: tsRef.current.hchartInstance.yAxis[0].min,
  //                   xAxis: 0,
  //                   yAxis: 0,
  //                 },
  //                 {
  //                   x: _end,
  //                   y: tsRef.current.hchartInstance.yAxis[0].max,
  //                   xAxis: 0,
  //                   yAxis: 0,
  //                 },
  //                 {
  //                   x: _start,
  //                   y: tsRef.current.hchartInstance.yAxis[0].max,
  //                   xAxis: 0,
  //                   yAxis: 0,
  //                 },
  //               ],
  //             },
  //           ],
  //           controlPoints: [
  //             {
  //               positioner: getPositioner(defalutData[i].id),
  //               events: {
  //                 drag(e: any, target: any) {
  //                   // eslint-disabled
  //                   const self: any = this;

  //                   const chart = self.chart;
  //                   const bbox = target.graphic.getBBox(true);

  //                   const center = {
  //                     x: bbox.x + bbox.width,
  //                     y: bbox.y + bbox.height,
  //                   };

  //                   const scale = self.mouseMoveToScale(e, center.x, center.y);
  //                   target.scale(center.x - chart.plotLeft, center.y - chart.plotTop, scale.x, 1);
  //                   target.redraw(false);
  //                 },
  //               },
  //             },
  //             {
  //               positioner: getPositioner(defalutData[i].id),
  //               events: {
  //                 // SCALE
  //                 drag(e: any, target: any) {
  //                   // eslint-disabled
  //                   const self: any = this;

  //                   const chart = self.chart;
  //                   const bbox = target.graphic.getBBox(true);
  //                   const center = {
  //                     x: bbox.x,
  //                     y: bbox.y,
  //                   };
  //                   const scale = self.mouseMoveToScale(e, center.x, center.y);
  //                   target.scale(center.x - chart.plotLeft, center.y - chart.plotTop, scale.x, 1);
  //                   target.redraw(false);
  //                 },
  //               },
  //             },
  //           ],
  //         };
  //         console.log('config');
  //         console.log(config);

  //         tsRef.current.hchartInstance.addAnnotation(config);
  //       }
  //     }

  //     setCurLabel({ ..._curLabel });
  //     setBrushData([...defalutData]);
  //     brushDataRef.current = [...defalutData];
  //     curLabelRef.current = _curLabel;
  //     firstRender.current = false;
  //   }
  // }, [defalutData, label, isChartLoaded]);

  React.useEffect(() => {
    addAnnotation(curPosition.start, curPosition.end);
  }, [curPosition]);

  const callback = debounce(
    (id: string, xMin: number, xMax: number) => {
      console.log('positioner', id, xMin, xMax);

      // const selectChartData = tsRef.current.data[0].filter((p: any) => p[0] >= xMin && p[0] <= xMax);

      // console.log('selectChartData');
      // console.log(selectChartData);

      // if (selectChartData.length > 0) {
      //   addAnnotation(selectChartData[0][0], selectChartData[selectChartD ata.length - 1][0], id);
      // }
    },
    200,
    false
  );

  const getPositioner = (id: string) => {
    return function (this: any, target: any) {
      // eslint-disabled
      const self: any = this;
      console.log('this ===================', this);
      console.log('target ===================', target);
      console.log('self ===================', self);

      // try {
      //   const xy = (window as any).Highcharts.Annotation.MockPoint.pointToPixels(target.points[self.index]);
      //   callback(id, target.points[0].x, target.points[2].x);
      //   return {
      //     x: xy.x - self.graphic.width / 2,
      //     y: xy.y / 2 - self.graphic.height / 2,
      //   };
      // } catch (ex) {
      //   console.error('ex', ex);
      //   return { x: 0, y: 0 };
      // }
    };
  };

  const addAnnotation = (xMin: number, xMax: number, id?: string) => {
    if (tsRef.current === null) return;

    if (id) {
      tsRef.current.hchartInstance.removeAnnotation(id);
    }

    const _guid = id ?? Guid().substring(0, 10);

    const fill = rgbaChangeAlpha(curLabelRef.current[`${curIndexRef.current}`]?.color || '', 0.4);
    const stroke = rgbaChangeAlpha(curLabelRef.current[`${curIndexRef.current}`]?.color || '', 0.6);

    const config = {
      id: _guid,
      draggable: 'x',
      events: {
        mouseover() {
          console.log('mouseover');
          tsRef.current.disableQuickOperation = true;
        },
        mouseout() {
          console.log('mouseout');
          tsRef.current.disableQuickOperation = false;
        },
      },
      shapes: [
        {
          type: 'path',
          strokeWidth: 1,
          stroke,
          fill,
          points: [
            {
              x: xMin,
              y: tsRef.current.hchartInstance.yAxis[0].min,
              xAxis: 0,
              yAxis: 0,
            },
            {
              x: xMax,
              y: tsRef.current.hchartInstance.yAxis[0].min,
              xAxis: 0,
              yAxis: 0,
            },
            {
              x: xMax,
              y: tsRef.current.hchartInstance.yAxis[0].max,
              xAxis: 0,
              yAxis: 0,
            },
            {
              x: xMin,
              y: tsRef.current.hchartInstance.yAxis[0].max,
              xAxis: 0,
              yAxis: 0,
            },
          ],
          controlPoints: [
            {
              positioner: getPositioner(_guid),
              height: 15,
              width: 15,
              visible: true,
              style: { strokeWidth: 1, stroke: 'red' },
              events: {
                drag(e: any, target: any) {
                  console.log('drag drag', e, target);
                  // eslint-disabled
                  const self: any = this;

                  const chart = self.chart;
                  const bbox = target.graphic.getBBox(true);

                  const center = {
                    x: bbox.x + bbox.width,
                    y: bbox.y + bbox.height,
                  };
                  e.prevChartX = 0;
                  e.chartX = 100;
                  const scale = self.mouseMoveToScale(e, center.x, center.y);
                  target.scale(center.x - chart.plotLeft, center.y - chart.plotTop, scale.x, 1);
                  target.redraw(false);
                },
              },
            },
            {
              positioner: getPositioner(_guid),
              height: 15,
              width: 15,
              visible: true,
              style: { strokeWidth: 1, stroke: 'red' },
              events: {
                // SCALE
                drag(e: any, target: any) {
                  // eslint-disabled
                  const self: any = this;

                  const chart = self.chart;
                  const bbox = target.graphic.getBBox(true);
                  const center = {
                    x: bbox.x,
                    y: bbox.y,
                  };
                  const scale = self.mouseMoveToScale(e, center.x, center.y);
                  target.scale(center.x - chart.plotLeft, center.y - chart.plotTop, scale.x, 1);
                  target.redraw(false);
                },
              },
            },
          ],
        },
      ],
    };

    tsRef.current.hchartInstance.addAnnotation(config);

    // 导出的数据格式
    _processTsSelect(_guid, xMin, xMax);

    // 取消对应的选中状态
    const _curLabel = curLabel;
    _curLabel[`${curIndex}`] = { value: '', color: '' };
    curLabelRef.current = _curLabel;
    setCurLabel({ ..._curLabel });

    console.log('选中区域之后执行=====结束');
  };

  // 这里只处理Ts类型的数据
  const renderBrushed = (min: number, max: number) => {
    console.log('这里只处理Ts类型的数据');
    console.log(min);
    console.log(max);
    console.log(curLabelRef.current);

    if (!curLabelRef.current[curIndexRef.current].value) return true;

    const selectChartData = tsRef.current.data[0].filter((p: any) => p[0] >= min && p[0] <= max);

    if (selectChartData.length === 0) return false;

    setCurPosition({ start: selectChartData[0][0], end: selectChartData[selectChartData.length - 1][0] });

    return false;
  };

  // 标签选择点击事件
  const onSelect = (lb: string, rgb: string, idx: number, type: string) => {
    //  =====设置当前选中的标签==============================================START
    const _curLabel = curLabelRef.current;
    // 多选标签 特殊情况特殊处理
    if (type === LABEL_TYPES.MULTIPLE_CHOICES) {
      let _lb = _curLabel[`${idx}`]?.value || [];
      if (typeof _lb != 'string') {
        const isIdx = _lb.findIndex((v) => v === lb);
        // 如果已经存在，再次点击就取消
        if (isIdx === -1) {
          _lb.push(lb);
        } else {
          _lb = _lb.filter((v) => v !== lb);
        }
      }
      _curLabel[`${idx}`] = {
        value: _lb,
        color: rgb,
      };
      setCurLabel({ ..._curLabel });
      curLabelRef.current = _curLabel;
    } else {
      _curLabel[`${idx}`] = {
        value: lb,
        color: rgb,
      };
      setCurLabel({ ..._curLabel });
      curLabelRef.current = _curLabel;
    }
    //  =====设置当前选中的标签===============================================END

    //  =====对各种类型的标签进行数据处理======================================START
    // 处理SINGLE_CHOICES类型的preview数据
    if (type === LABEL_TYPES.SINGLE_CHOICES || type === LABEL_TYPES.MULTIPLE_CHOICES) {
      _processSingleChoiceSelect(type);
    }
    //  =====对各种类型的标签进行数据处理========================================END

    console.log(curLabelRef);
  };

  // 处理ts类型的preview数据
  const _processTsSelect = (id: string, xMin: number, xMax: number) => {
    const _brushData: IbrushData = {
      value: {
        start: xMin,
        end: xMax,
        [label[curIndexRef.current].type]: [curLabelRef.current[`${curIndexRef.current}`]?.value || ''],
        color: curLabelRef.current[`${curIndexRef.current}`]?.color || '',
      },
      id,
      type: label[curIndexRef.current].type,
    };
    // 如果有二级的key，则将key放到value上
    if (secondKey) {
      _brushData.value.key = secondKey;
    }
    if (title) {
      _brushData.title = title;
    }
    if (topic) {
      _brushData.topic = topic;
    }
    brushData.push(_brushData);

    setBrushData([...brushData]);
    brushDataRef.current = [...brushData];

    onBrushChange && onBrushChange([...brushData]);
  };

  // 处理choice类型的preview数据
  const _processSingleChoiceSelect = (type: string) => {
    const selectedItems = brushData;
    const _idx = selectedItems.findIndex((v) => v.type === type);
    const _brushData: IbrushData = {
      value: {
        [label[curIndexRef.current].type]:
          type === LABEL_TYPES.MULTIPLE_CHOICES
            ? curLabelRef.current[`${curIndexRef.current}`].value
            : [curLabelRef.current[`${curIndexRef.current}`].value],
      },
      id: _idx >= 0 ? selectedItems[_idx].id : Guid().substring(0, 10), // 如果已经存在ID不变
      type: label[curIndexRef.current].type,
    };
    // 如果有二级的key，则将key放到value上
    if (secondKey) {
      _brushData.value.key = secondKey;
    }
    if (title) {
      _brushData.title = title;
    }
    if (topic) {
      _brushData.topic = topic;
    }
    if (_idx === -1) {
      selectedItems.push(_brushData);
    } else {
      selectedItems[_idx] = _brushData;
    }

    setBrushData([...selectedItems]);
    brushDataRef.current = [...selectedItems];
    onBrushChange && onBrushChange([...selectedItems]);
  };

  return (
    <>
      {label.map((lb: any, idx: number) => (
        <Label
          key={Guid()}
          data={lb.data}
          type={lb.type}
          current={curLabel[`${idx}`]?.value || ''}
          onClick={(_lb: string, _rgb: string = '') => {
            setCurIndex(idx);
            curIndexRef.current = idx;
            onSelect(_lb, _rgb, idx, lb.type);
          }}
        />
      ))}
      <div style={{ width: '100%', height: 300 }}>
        <BaseChart
          getChart={(_chart: any) => {
            yPosition.current = {
              min: _chart.hchartInstance.yAxis[0].min,
              max: _chart.hchartInstance.yAxis[0].max,
            };
            tsRef.current = _chart;
            setIsChartLoaded(true);
          }}
          chartData={value}
          onMainCursorMoved={(selectedX: number, selectedY: number, data: any, args: string) => {
            onNodeClick && onNodeClick({ selectedX, selectedY, data, args });
          }}
          onSetExtremes={renderBrushed}
        />
      </div>
    </>
  );
};

export default RzTimeSeries;
